package cn.ivicar.sim.service;

import java.math.BigDecimal;
import java.util.*;
import java.util.Map.Entry;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.carsmart.exception.BadRequestException;
import cn.com.carsmart.exception.CarsmartException;
import cn.com.carsmart.ws.model.AppPay;
import cn.com.carsmart.ws.model.SimChargeRecord;
import cn.ivicar.sim.util.Md5Utils;
import cn.ivicar.sim.util.SimProperties;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import weixin.popular.api.PayMchAPI;
import weixin.popular.bean.paymch.Unifiedorder;
import weixin.popular.bean.paymch.UnifiedorderResult;

/**
 * Created by lixiaozhuo on 17/5/21.
 */
public class SimRpcService {
	
	private static transient final Logger LOGGER = LoggerFactory.getLogger(SimRpcService.class);


	private static final String URL_DOMAIN = "http://iot.hbsmservice.com:8096/iot_platform_interface/";
	private static final String USER_ID = "bjxyq9706";
	private static final String USER_PWD = "bjxy007";

	private static final String URL_SIM_BASE_INFO = URL_DOMAIN + "iotSearchCardBaseInfo.do";
	private static final String URL_SIM_STATUS_BATCH = URL_DOMAIN + "iotSearchCardStatus.do";
	private static final String URL_SIM_STATUS_REALTIME = URL_DOMAIN + "iotRealTimeSearchCardStatus.do";
	private static final String URL_GPRS_STATUS_REALTIME = URL_DOMAIN + "iotRealTimeSearchGprsStatus.do";
	private static final String URL_SWITCH_STATUS_REALTIME = URL_DOMAIN + "iotRealTimeSearchSwitchStatus.do";
	private static final String URL_SIM_FLOW_USED_MONTHLY_BATCH = URL_DOMAIN + "iotSearchRealTimeSpendFlow.do";
	private static final String URL_UPDATE_SWITCH_STATUS = URL_DOMAIN + "iotUpdateSwitchStatusInfo.do";
	private static final String URL_UPDATE_GPRS_STATUS = URL_DOMAIN + "iotUpdateGprsStatusInfo.do";
	private static final String URL_SIM_FLOW_USED_MONTHLY_REALTIME = URL_DOMAIN + "iotRealTimeSearchFlowSpendPackage.do";
	private static final String URL_SIM_FLOW_USED_DAILY_BATCH = URL_DOMAIN + "iotSearchTheDaySpendFlow.do";

    private static final String URL_SIM_INFO = "http://wl.51liubei.com/dhApi/iotCardInfoApi.api?entCode=660608&iccid=%s&access_token=%s&secret=16ABDB4A70511D63426B8B65C7AD4DC6";
    private static final String URL_DAILY_FLOW = "http://wl.51liubei.com/dhApi/iotCardetailApi.api?entCode=660608&iccid=%s&access_token=%s&secret=16ABDB4A70511D63426B8B65C7AD4DC6";
    private static final String URL_FLOW_PACKAGE = "http://wl.51liubei.com/dhApi/iotCardAddFlowCheckApi.api?entCode=660608&iccid=%s&access_token=%s&secret=16ABDB4A70511D63426B8B65C7AD4DC6";
    private static final String URL_BUY_FLOW_PACKAGE = "http://wl.51liubei.com/dhApi/iotCardAddFlowApi.api?entCode=660608&iccid=%s&access_token=%s&secret=16ABDB4A70511D63426B8B65C7AD4DC6&tcsyid=%s&outtradeno=%s";
    private static final String URL_WECHAT_PAY = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    private static final String entCode = "660608";
    private static final String secret = "16ABDB4A70511D63426B8B65C7AD4DC6";

    //TODO
    private static final String WECHAT_NOTIFY_URL = SimProperties.getWechatNotifyUrl();
//    private static final String WECHAT_NOTIFY_URL = "http://apiserver.ivicar.cn/app-ws/wechat";

    private static final String SIM_KEY = "2weatyhgfeb330459878bnmklpd90g49";

    private static final String SUCCESS_CODE = "40000";
    public static final String SUCCESS_FLAG = "SUCCESS";
    public static final String FAIL_FLAG = "FAIL";
    public static final String KEY_RETURN_CODE = "return_code";
    private static final String KEY_RETURN_INFO = "return_info";
    private static final String KEY_RESULT_CODE = "result_code";
    
    

    public static JSONObject getSimInfo(String iccid){
        String columnName = "iccid";
        String transId = String.valueOf(System.currentTimeMillis());
        Map<String, String> params = generateCommonParams(columnName, iccid, transId);
        List<String> signParams = new ArrayList<>();
        signParams.add(columnName);
        signParams.add(iccid);
        signParams.add(transId);
        signParams.add(USER_ID);
        signParams.add(USER_PWD);
        String sign = createSign(signParams);
        params.put("sign", sign);


        String result = sendPostRequest(URL_SIM_BASE_INFO, params);
        if(StringUtils.isBlank(result)){
            return null;
        }

        JSONObject json = JSONObject.fromObject(result);
        return json;
//        if(SUCCESS_CODE.equals(json.getString(KEY_RETURN_CODE))){
//            return json.getJSONArray(KEY_RETURN_INFO).getJSONObject(0);
//        }else{
//            System.out.println("第三方接口返回查询失败 " + json);
//            return  null;
//        }
    }

    //批量获取卡状态
    public static JSONObject getSimStatusBatch(String iccid){
        String columnName = "iccid";
        String transId = String.valueOf(System.currentTimeMillis());
        Map<String, String> params = generateCommonParams(columnName, iccid, transId);
        List<String> signParams = new ArrayList<>();
        signParams.add(columnName);
        signParams.add(iccid);
        signParams.add(transId);
        signParams.add(USER_ID);
        signParams.add(USER_PWD);
        String sign = createSign(signParams);
        params.put("sign", sign);


        String result = sendPostRequest(URL_SIM_STATUS_BATCH, params);
        if(StringUtils.isBlank(result)){
            return null;
        }

        JSONObject json = JSONObject.fromObject(result);
        return json;
//        if(SUCCESS_CODE.equals(json.getString(KEY_RETURN_CODE))){
//            return json.getJSONArray(KEY_RETURN_INFO).getJSONObject(0);
//        }else{
//            System.out.println("第三方接口返回查询失败 " + json);
//            return  null;
//        }
    }

    //实时获取卡状态（单个）
    public static JSONObject getSimStatusRealtime(String iccid){
        String columnName = "iccid";
        String transId = String.valueOf(System.currentTimeMillis());
        Map<String, String> params = generateCommonParams(columnName, iccid, transId);
        List<String> signParams = new ArrayList<>();
        signParams.add(columnName);
        signParams.add(iccid);
        signParams.add(transId);
        signParams.add(USER_ID);
        signParams.add(USER_PWD);
        String sign = createSign(signParams);
        params.put("sign", sign);


        String result = sendPostRequest(URL_SIM_STATUS_REALTIME, params);
        if(StringUtils.isBlank(result)){
            return null;
        }

        JSONObject json = JSONObject.fromObject(result);
        return json;
    }

    //实时获取GPRS状态（单个）
    public static JSONObject getGPRSStatusRealtime(String iccid){
        String columnName = "iccid";
        String transId = String.valueOf(System.currentTimeMillis());
        Map<String, String> params = generateCommonParams(columnName, iccid, transId);
        List<String> signParams = new ArrayList<>();
        signParams.add(columnName);
        signParams.add(iccid);
        signParams.add(transId);
        signParams.add(USER_ID);
        signParams.add(USER_PWD);
        String sign = createSign(signParams);
        params.put("sign", sign);


        String result = sendPostRequest(URL_GPRS_STATUS_REALTIME, params);
        if(StringUtils.isBlank(result)){
            return null;
        }

        JSONObject json = JSONObject.fromObject(result);
        return json;
    }

    //实时获取设备状态（单个）
    public static JSONObject getSwitchStatusRealtime(String iccid){
        String columnName = "iccid";
        String transId = String.valueOf(System.currentTimeMillis());
        Map<String, String> params = generateCommonParams(columnName, iccid, transId);
        List<String> signParams = new ArrayList<>();
        signParams.add(columnName);
        signParams.add(iccid);
        signParams.add(transId);
        signParams.add(USER_ID);
        signParams.add(USER_PWD);
        String sign = createSign(signParams);
        params.put("sign", sign);

        String result = sendPostRequest(URL_SWITCH_STATUS_REALTIME, params);
        if(StringUtils.isBlank(result)){
            return null;
        }

        JSONObject json = JSONObject.fromObject(result);
        return json;
    }

    //queryDate: yyyy-MM-dd
    public static JSONObject getDailyFlowUsed(String iccid, String queryDate){
        String columnName = "iccid";
        String transId = String.valueOf(System.currentTimeMillis());
        Map<String, String> params = generateCommonParams(columnName, iccid, transId);
        params.put("queryDate", queryDate);
        List<String> signParams = new ArrayList<>();
        signParams.add(columnName);
        signParams.add(iccid);
        signParams.add(queryDate);
        signParams.add(transId);
        signParams.add(USER_ID);
        signParams.add(USER_PWD);
        String sign = createSign(signParams);
        params.put("sign", sign);


        String result = sendPostRequest(URL_SIM_FLOW_USED_DAILY_BATCH, params);
        if(StringUtils.isBlank(result)){
            return null;
        }

        JSONObject json = JSONObject.fromObject(result);
        return json;
    }

    //批量查询月使用流量
    public static JSONObject getMonthlyFlowUsedBatch(String iccid){
        String columnName = "iccid";
        String transId = String.valueOf(System.currentTimeMillis());
        Map<String, String> params = generateCommonParams(columnName, iccid, transId);
        List<String> signParams = new ArrayList<>();
        signParams.add(columnName);
        signParams.add(iccid);
        signParams.add(transId);
        signParams.add(USER_ID);
        signParams.add(USER_PWD);
        String sign = createSign(signParams);
        params.put("sign", sign);


        String result = sendPostRequest(URL_SIM_FLOW_USED_MONTHLY_BATCH, params);
        if(StringUtils.isBlank(result)){
            return null;
        }

        JSONObject json = JSONObject.fromObject(result);
        return json;
    }

    //实时查询月使用流量（只支持单个查询）
    public static JSONObject getMonthlyFlowUsedRealtime(String iccid){
        String columnName = "iccid";
        String transId = String.valueOf(System.currentTimeMillis());
        Map<String, String> params = generateCommonParams(columnName, iccid, transId);
        List<String> signParams = new ArrayList<>();
        signParams.add(columnName);
        signParams.add(iccid);
        signParams.add(transId);
        signParams.add(USER_ID);
        signParams.add(USER_PWD);
        String sign = createSign(signParams);
        params.put("sign", sign);


        String result = sendPostRequest(URL_SIM_FLOW_USED_MONTHLY_REALTIME, params);
        if(StringUtils.isBlank(result)){
            return null;
        }

        JSONObject json = JSONObject.fromObject(result);
        return json;
    }

    //停复机操作
    public static JSONObject updateSwitchStatus(String iccid, String targetStatus){
        String columnName = "iccid";
        String transId = String.valueOf(System.currentTimeMillis());
        Map<String, String> params = generateCommonParams(columnName, iccid, transId);
        params.put("user_status", targetStatus);
        List<String> signParams = new ArrayList<>();
        signParams.add(columnName);
        signParams.add(iccid);
        signParams.add(targetStatus);
        signParams.add(transId);
        signParams.add(USER_ID);
        signParams.add(USER_PWD);
        String sign = createSign(signParams);
        params.put("sign", sign);


        String result = sendPostRequest(URL_UPDATE_SWITCH_STATUS, params);
        if(StringUtils.isBlank(result)){
            return null;
        }

        JSONObject json = JSONObject.fromObject(result);
        return json;
    }

    //停复机操作
    public static JSONObject updateGPRSStatus(String iccid, String targetStatus){
        String columnName = "iccid";
        String transId = String.valueOf(System.currentTimeMillis());
        Map<String, String> params = generateCommonParams(columnName, iccid, transId);
        params.put("oper_type", targetStatus);
        List<String> signParams = new ArrayList<>();
        signParams.add(columnName);
        signParams.add(iccid);
        signParams.add(targetStatus);
        signParams.add(transId);
        signParams.add(USER_ID);
        signParams.add(USER_PWD);
        String sign = createSign(signParams);
        params.put("sign", sign);


        String result = sendPostRequest(URL_UPDATE_GPRS_STATUS, params);
        if(StringUtils.isBlank(result)){
            return null;
        }

        JSONObject json = JSONObject.fromObject(result);
        return json;
    }

    public static JSONArray getAvailableFlowPackage(String iccid){
        SortedMap<String, String> map = new TreeMap<String, String>();
        map.put("entCode", entCode);
        map.put("secret", secret);
        map.put("iccid", iccid);

        String accessToken = createAccessToken(map, SIM_KEY);
        String url = String.format(URL_FLOW_PACKAGE, iccid, accessToken);
        System.out.println(url);
        String result = getHtmlContent(url);
        if(StringUtils.isBlank(result)){
            return null;
        }

        JSONObject json = JSONObject.fromObject(result);
        if(SUCCESS_CODE.equals(json.getString(KEY_RETURN_CODE))){
            return json.getJSONArray(KEY_RETURN_INFO);
        }else{
            System.out.println("第三方接口返回查询失败 " + json);
            return  null;
        }
    }

    public static JSONObject buyFlowPackage (String iccid, String flowPackageId, String recordId){
        SortedMap<String, String> map = new TreeMap<String, String>();
        map.put("entCode", entCode);
        map.put("secret", secret);
        map.put("tcsyid", flowPackageId);
        map.put("iccid", iccid);

        String accessToken = createAccessToken(map, SIM_KEY);
        String url = String.format(URL_BUY_FLOW_PACKAGE, iccid, accessToken, flowPackageId, recordId);
        String result = getHtmlContent(url);
        if(StringUtils.isBlank(result)){
            return null;
        }

        JSONObject json = JSONObject.fromObject(result);
        if(SUCCESS_CODE.equals(json.getString(KEY_RETURN_CODE))){
            return json;
        }else{
            System.out.println("第三方接口购买流量包失败 " + json);
            return  null;
        }
    }

    private static String getHtmlContent(String url){
        String content = "";
        HttpClient client = new HttpClient();
        GetMethod method = new GetMethod(url);

        try {
            int statusCode = client.executeMethod(method);
            if (statusCode != HttpStatus.SC_OK) {
                System.out.println("get请求失败:  statusCode:" + statusCode + " statusLine:" + method.getStatusLine());
            } else {
                content = method.getResponseBodyAsString();
            }
        }catch(Exception e){
            e.printStackTrace();
        }

        return content;
    }

    private static String sendPostRequest(String url, Map<String, String> params){
        System.out.println("url=" + url);
        System.out.println("params=" + params);
        String content = "";
        HttpClient client = new HttpClient();
        PostMethod method = new PostMethod(url);

        Iterator<Entry<String, String>> ps = params.entrySet().iterator();
        while (ps.hasNext()) {
            Map.Entry<String, String> p = ps.next();
            method.addParameter(p.getKey(), p.getValue().toString());
        }

        try {
            int statusCode = client.executeMethod(method);
            if (statusCode != HttpStatus.SC_OK) {
                System.out.println("post请求失败:  statusCode:" + statusCode + " statusLine:" + method.getStatusLine());
            } else {
                content = method.getResponseBodyAsString();
            }
        }catch(Exception e){
            e.printStackTrace();
        }

        return content;
    }

    public static String createAccessToken(SortedMap<String, String> packageParams, String key) {
//        String   key="2weatyhgfeb330459878bnmklpd90g49";
        String charset="UTF-8";

        StringBuffer sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = entry.getValue().toString();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + key);
        System.out.println("md5 sb:" + sb);
        String sign = Md5Utils.MD5Encode(sb.toString(), charset, true);
        System.out.println("packge签名:" + sign);
        return sign;

    }

    private static String createSign(List<String> params){
        String charset="UTF-8";
        StringBuffer sbuf = new StringBuffer();
        for(String temp : params){
            sbuf.append(temp);
        }

        return Md5Utils.MD5Encode(sbuf.toString(), charset, false);
    }

    private static Map<String, String> generateCommonParams(String columnName, String columnValue, String transId){
        Map<String, String> params = new HashMap<>();
        params.put("userId", USER_ID);
        params.put("transId", transId);
        params.put("column_name", columnName);
        params.put("column_value", columnValue);

        return params;
    }

//    public static void main(String[] args) {
//        String charset="UTF-8";
//        String test = "iccid" + "898607B1101730308338" + "1234" + "bjxyq9706" + "bjxy007";
//        String sign = Md5Utils.MD5Encode(test, charset, true);
//        System.out.println(sign);
//    }

    public static void main(String[] args) {
//        String iccid = "898607B1101730308338,898607B1101730308339";
        String iccid = "898607B1101730308339";
        JSONObject json = getDailyFlowUsed(iccid, "2017-08-12");
//        JSONObject json = getMonthlyFlowUsedRealtime(iccid);
        System.out.println(json);
    }

    public static JSONObject payByWechat(SimChargeRecord simChargeRecord, String ip, AppPay appPayInfo,String productName) throws CarsmartException{
    	
        Unifiedorder unifiedorder = new Unifiedorder();
		unifiedorder.setAppid(appPayInfo.getPayAppId());
		unifiedorder.setMch_id(appPayInfo.getMchId());
		unifiedorder.setNonce_str(UUID.randomUUID().toString().replace("-", ""));
		unifiedorder.setBody(productName);
		unifiedorder.setOut_trade_no("" + simChargeRecord.getChargeId() + "");
		unifiedorder.setTotal_fee(simChargeRecord.getChargeAmount().multiply(BigDecimal.valueOf(100)).intValue() + "");//单位分
		unifiedorder.setNotify_url(WECHAT_NOTIFY_URL);
		unifiedorder.setTrade_type("APP");//JSAPI，NATIVE，APP，MWEB

		UnifiedorderResult unifiedorderResult = null;
		try {
			unifiedorderResult = PayMchAPI.payUnifiedorder(unifiedorder,appPayInfo.getAppKey());
			
		}  catch (Exception e1) {
			e1.printStackTrace();
            throw new BadRequestException("400", "发起预支付失败!");
		}
		
		if(unifiedorderResult.getSign_status() ==null || !unifiedorderResult.getSign_status()){
			throw new BadRequestException("400", "发起预支付失败!");
		}
		
		
        
        if(unifiedorderResult.getReturn_code().equals(FAIL_FLAG) || unifiedorderResult.getResult_code().equals(FAIL_FLAG)){
            throw new BadRequestException("400", "发起预支付失败!");
        }

        JSONObject response = new JSONObject();
        if(unifiedorderResult.getReturn_code().equals(SUCCESS_FLAG) && unifiedorderResult.getResult_code().equals(SUCCESS_FLAG)){
            response.put("payappid", unifiedorderResult.getAppid());
            response.put("partnerid", unifiedorderResult.getMch_id());
            response.put("prepay_id", unifiedorderResult.getPrepay_id());
            response.put("noncestr", unifiedorderResult.getNonce_str());
            response.put("timestamp", System.currentTimeMillis()/1000+"");
            //response.put("package", "prepay_id="+unifiedorderResult.getPrepay_id());
            response.put("package", "Sign=WXPay");
            
            response.put("sign", unifiedorderResult.getSign());
            response.put("notify_url", WECHAT_NOTIFY_URL);
        }

        return response;
    }
    
    private static String getUUID(){
        UUID uuid = UUID.randomUUID();
        return uuid.toString().replace("-", "");
    }

}
